﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Text;
using Fcdbas.Core;
using Fcdbas.Core.Reflection;
using Fcdbas.Core.Exceptions;
using Fcdbas.DataContract;
namespace Fcdbas.Platform
{
    /// <summary>
    /// 业务处理基类，提供基本数据的增、删、改操作
    /// </summary>
    public class FunctionClassBase : SalFunctionalClass,Fcdbas.Platform.IFunctionClassBase
    {
       
        //private IEntity __entity;
        public string ErrorMsg
        {
            get;
            set;
        }
        public int ErrorCode
        {
            get;
            set;
        }
        
        public FunctionClassBase()
        {
            
        }
        //public virtual int PrepareSQLBlock(string sSql, Dictionary<string, object> parms, CommandType type = CommandType.StoredProcedure)
        //{
        //    return 0;
        //}
        //public virtual int PrepareSQLBlock(IEntity Entity, string sSql, bool IsStandard = true, bool IsFirst = false, Dictionary<string, string> association = null, CommandType type = CommandType.StoredProcedure, int KeyRef = 0)
        //{
        //    return 0;
        //}
        //public virtual ExecuteResult BatchExecute()
        //{
        //    return true;
        //}
        //public IEntity Entity
        //{
        //    get { return __entity; }
        //    set { __entity = value; }
        //}

        
        /// <summary>
        /// 开始一个事务
        /// </summary>
        /// <param name="sSql"></param>
        /// <returns></returns>
        public virtual SalBoolean DbTransactionBegin(IEntity Entity)
        {
            return Entity.BeginTrans();
        }
       
        /// <summary>
        /// 回滚当前事务
        /// </summary>
        /// <returns></returns>
        public virtual SalBoolean DbTransactionClear(IEntity Entity)
        {
            Int32 res= Entity.Rollback();
            if (res == 0)
                return true;
            else
                return false;
        }
        /// <summary>
        /// 提交当前事务
        /// </summary>
        /// <returns></returns>
        public virtual SalBoolean DbTransactionEnd(IEntity Entity)
        {
            Int32 res= Entity.Commit();
            if (res == 0)
                return true;
            else
                return false;
        }
        /// <summary>
        /// 调用存储过程或者函数,不会自动提交, 可能多个Block一起执行， 一般会和DbTransactionBegin一起使用
        /// </summary>
        /// <param name="sSql">SQL格式为：Result := StoredProcessdure(:Name,:Id)</param>
        /// <returns></returns>
        public virtual SalBoolean DbMySQLBlock(IEntity Entity,SalString sSql)
        {
            ErrorCode = 0;
            ErrorMsg = "";
            Int32 res = Entity.ExecuteStoredProcedure(sSql);
            if (res == -1)
            {
                string msg = "";
                ErrorCode = Entity.GetSqlException(ref msg);
                ErrorMsg = msg;

            }
            // return res;
            if (res >= 0)
                return true;
            else
                return false;
        }
        /// <summary>
        /// 调用存储过程或者函数,不会自动提交, 可能多个Block一起执行， 一般会和DbTransactionBegin一起使用
        /// </summary>
        /// <param name="sSql">SQL格式为：Result := StoredProcessdure(:Name,:Id)</param>
        /// <returns></returns>
        public virtual SalNumber DbMySQLBlock(IEntity Entity, SalString sSql, Dictionary<SalString, object> parms, CommandType type = CommandType.StoredProcedure)
        {
            ErrorCode = 0;
            ErrorMsg = "";
            Int32 res = Entity.Execute(sSql, parms, type);
            if (res == -1)
            {
                string msg = "";
                ErrorCode = Entity.GetSqlException(ref msg);
                ErrorMsg = msg;

            }
            // return res;
            if (res >= 0)
                return true;
            else
                return false;
        }
        
        /// <summary>
        /// 调用存储过程或者函数,自动提交
        /// </summary>
        /// <param name="sSql">SQL格式为：Result := StoredProcessdure(:Name,:Id)</param>
        /// <returns></returns>
        public virtual SalBoolean DbMySQLTransaction(IEntity Entity,SalString sSql)
        {
            Entity.BeginTrans();
            SalBoolean res = Entity.ExecuteStoredProcedure(sSql);
            SalBoolean r = false;
            if (res)
                r = Entity.Commit();
            else
                r = Entity.Rollback();
            return r;
        }

        /// <summary>
        /// 调用存储过程或者函数,自动提交
        /// </summary>
        /// <param name="sSql">SQL格式为：Result := StoredProcessdure(:Name,:Id)</param>
        /// <returns></returns>
        public virtual SalBoolean DbMySQLTransaction(IEntity Entity,SalString sSql,Dictionary<SalString,object> parms,CommandType type = CommandType.StoredProcedure)
        {
            Entity.BeginTrans();
            SalBoolean res = Entity.Execute(sSql,parms,type);
            SalBoolean r = false;
            if (res)
                r = Entity.Commit();
            else
                r = Entity.Rollback();
            return r;
        }
        /// <summary>
        /// 当前抽取数据的位置
        /// </summary>
        public int RecordPos = 0;
        protected IEntityList EntityList = null;
        /// <summary>
        /// 根据条件取得数据实体列表
        /// </summary>
        /// <param name="where"></param>
        /// <param name="orderby"></param>
        /// <param name="mode">抽取模式,1抽取下一段,2抽取所有,3重新抽取,4刷新当前记录</param>
        /// <returns></returns>
        public virtual IEntityList Find(IEntity Entity, SalString where, SalString fields, SalString orderby, int mode, int RecordLimit)
        {
            //我刚才给你的备份,里面有一个Funciton: FndVpdPolicy_GetPolicy, 这个是你Call所有的视图的时候, 都需要调用下,返回字符串,是额外需要合并在一起的Where条件
//如果为null或者'',就不用管
            if (Entity == null)
            {
                Fcdbas.Core.Log.XTrace.WriteLine(string.Format("Find Entity is null"));
                return null;
            }
            Type[] tps = new Type[5];
            for (int i = 0; i < 5; i++)
            {
                if (i < 3)
                    tps[i] = typeof(string);
                if (i >= 3)
                    tps[i] = typeof(Int32);
            }
            
            MethodInfoX method = MethodInfoX.Create(Entity.GetType(), "FindAll", tps);
            Fcdbas.Core.Log.XTrace.WriteLine(string.Format("执行查询，对象类型是：{0},where 条件是：{1},字段：{2},模式：{3},orderby:{4}", Entity.GetType().ToString(), where, fields, mode, orderby));
            object res = null;
            if (mode == 4 && Entity["objid"] != null)
            {
                where = "objid = '" + Entity["objid"].ToString() + "'";

                IEntityList list1 = method.Invoke(method, where, orderby, fields, 0, 0) as IEntityList;
                if (list1 == null || list1.Count == 0)
                    return EntityList;
                if (EntityList == null || EntityList.Count == 0)
                {
                    EntityList = list1;
                    return EntityList;
                }
                IEntity enN = list1[0];
                IEntity enO = EntityList.Find("objid", Entity["objid"]);
                enO.CopyFrom(enN);
                return EntityList;
            }
            //Entity<IEntity>.FindAll();
            switch (mode)
            {
                case 3:
                    if (RecordCount >= RecordLimit)
                    {
                        res = method.Invoke(method, where, orderby, fields, 0, RecordLimit);
                        if (RecordLimit != 0)
                            RecordPos = RecordLimit;
                        else
                            RecordPos = 0;
                    }
                    else
                    {
                        res = method.Invoke(method, where, orderby, fields, 0, 0);
                        RecordPos = 0;
                    }
                    EntityList = res as IEntityList;
                    break;
                case 1:
                    IEntityList list;
                    if (RecordCount >= RecordPos + RecordLimit)
                        list = method.Invoke(method, where, orderby, fields, RecordPos, RecordLimit) as IEntityList;
                    else
                    {
                        int nCount = RecordCount - RecordPos;
                        if (nCount <= 0)
                            return EntityList;
                        list = method.Invoke(method, where, orderby, fields, RecordPos, nCount) as IEntityList;
                    }
                   
                    if (this.EntityList == null)
                    {
                        this.EntityList = list;
                    }
                    else
                    {
                        foreach (var en in list)
                        {
                            EntityList.Add(en);
                        }
                    }
                    if (RecordLimit != 0)
                        RecordPos = RecordPos + RecordLimit;
                    else
                        RecordPos = 0;
                   // EntityList = res as IEntityList;
                    
                    break;
                case 2:
                    res = method.Invoke(method, where, orderby, fields, 0, 0);
                    
                    EntityList = res as IEntityList;
                   
                    break;
            }
            
            return EntityList;
        }
        /// <summary>
        /// 记录总数
        /// </summary>
        protected int RecordCount = 0;
        /// <summary>
        /// 查询总数
        /// </summary>
        /// <param name="Entity"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public virtual int FindCount(IEntity Entity, SalString where)
        {
            return 0;
           
        }
    }
}
